package org.squabble.web.account;

import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.RememberMeAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Validator;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;
import org.squabble.SquabbleConstants;
import org.squabble.domain.Account;
import org.squabble.service.AccountService;
import org.squabble.service.LoginService;

@Controller
@RequestMapping("/account/register")
@SessionAttributes(value = { "account" })
public class RegisterController {

	protected final Log logger = LogFactory.getLog(getClass());

	@Autowired
	@Qualifier("validator")
	Validator validator;

	@Autowired
	LoginService loginService;

	@Autowired
	@Qualifier("authenticationManager")
	ProviderManager providerManager;

	@Autowired
	AccountService accountService;

	@RequestMapping(method = RequestMethod.GET)
	public String setupForm(ModelMap model) throws Exception {
		// TODO Auto-generated method stub
		RegisterCommand rc = new RegisterCommand();
		model.addAttribute("registerCommand", rc);
		return "account.register";
	}

	@RequestMapping(method = RequestMethod.POST)
	public String processSubmit(
			@ModelAttribute("registerCommand") RegisterCommand rc,
			BindingResult result, SessionStatus status, ModelMap model,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		validator.validate(rc, result);
		if (result.hasErrors()) {
			return "account.register";
		}
		Account account = accountService.registerAccount(rc);
		request.getSession().setAttribute("account", account);
		Authentication auth = new RememberMeAuthenticationToken(loginService
				.getKey(), account, account.getAuthorities());
		// auth = providerManager.doAuthentication(auth);
		// SecurityContextHolder.getContext().setAuthentication(auth);
		// Place the new Authentication object in the security context.
		SecurityContextHolder.getContext().setAuthentication(auth);
		auth = SecurityContextHolder.getContext().getAuthentication();
		loginService.onLoginSuccess(request, response, auth);
		request
				.getSession()
				.setAttribute(
						HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY,
						SecurityContextHolder.getContext());
		model.addAttribute(SquabbleConstants.POST_PROCESS_MESSAGE,
		"register.processed");		
		return "redirect:/account/home";
	}

	@InitBinder
	public void initBinder(WebDataBinder binder) {
		SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
		CustomDateEditor cde = new CustomDateEditor(sdf, true);
		binder.registerCustomEditor(Date.class, cde);
	}

}
